package com.ziq.zcamp.manager

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Resources
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.annotation.StringRes
import com.ziq.base.utils.ProcessUtils
import com.ziq.zcamp.main.MainActivity
import java.lang.ref.WeakReference
import java.util.*

object GlobalContextManager {


    fun init(app: Application){
        application = app
        appContext = app
        app.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
            override fun onActivityCreated(
                activity: Activity,
                savedInstanceState: Bundle?
            ) {
                addLiveActivity(activity)
            }

            override fun onActivityStarted(activity: Activity) {
                pushCurrentActivity(activity)
            }

            override fun onActivityResumed(activity: Activity) {
                pushCurrentActivity(activity)
            }

            override fun onActivityPaused(activity: Activity) {
                popCurrentActivity(activity)
            }

            override fun onActivityStopped(activity: Activity) {
            }

            override fun onActivitySaveInstanceState(
                activity: Activity,
                outState: Bundle
            ) {
            }

            override fun onActivityDestroyed(activity: Activity) {
                removeLiveActivity(activity)
            }
        })
    }

    val mainHandler = Handler(Looper.getMainLooper())

    /**
     * 这两个是应用全局对象，和进程生命周期一致，所以静态持有是没有问题的
     */
    @Volatile
    var application: Application? = null
        get() {
            if (field == null) {
                throw RuntimeException("GlobalContext application 没有初始化赋值")
            }
            return field
        }

    @Volatile
    var appContext: Context? = null
        get() {
            if (field == null) {
                throw RuntimeException("GlobalContext appContext 没有初始化赋值")
            }
            return field
        }

    private val mCurrentActivity = Stack<WeakReference<Activity>>()
    private val mLivedActivity = mutableListOf<WeakReference<Activity>>()

    fun isMainProcess(): Boolean {
        return appContext?.packageName.equals(getCurrentProcessName())
    }

    fun getPackageManager(): PackageManager? {
        return appContext?.packageManager
    }

    fun getPackageName(): String? {
        return appContext?.packageName
    }

    /**
     * 获取当前进程名
     */


    @SuppressLint("RestrictedApi")
    fun getCurrentProcessName(): String? {
        return ProcessUtils.getCurrentProcessName(appContext!!)
    }

    fun pushCurrentActivity(activity: Activity) {
        if(mCurrentActivity.empty()){
            mCurrentActivity.push(WeakReference(activity))
        } else {
            val activityWeakReference: WeakReference<Activity> = mCurrentActivity.peek()
            if (activityWeakReference.get() !== activity) {
                mCurrentActivity.push(WeakReference(activity))
            }
        }
    }

    fun popCurrentActivity(activity: Activity?) {
        if (mCurrentActivity.empty() || activity == null) {
            return
        }
        // 当退出一个ActivityA，快速打开ActivityB时，有时会发生ActivityA->onDestory() 慢于 ActivityB->onCreate()
        // 这样过去用 Classname 判断时，如果ActivityA 与 ActivityB 是同一个类，那么会错误的置空
        // if (TextUtils.equals(currentActivity.getClass().getName(), activity.getClass().getName())) {
        val activityWeakReference: WeakReference<Activity> = mCurrentActivity.peek()
        if (activityWeakReference.get() === activity) {
            mCurrentActivity.pop()
        }
    }

    fun addLiveActivity(activity: Activity) {
        val activityWeakReference = WeakReference(activity)
        mLivedActivity.add(activityWeakReference)
    }

    fun removeLiveActivity(activity: Activity?) {
        if (mLivedActivity.isEmpty() || activity == null) {
            return
        }
        for (item in mLivedActivity){
            if(item.get() != null && item.get() == activity){
                mLivedActivity.remove(item)
                break
            }
        }
    }

    fun hasMainActivity():Boolean{
        if (mLivedActivity.isNotEmpty()) {
            for(activity in mLivedActivity){
                if(activity.get() != null && activity.get() is MainActivity){
                    return true
                }
            }
        }
        return false
    }

    fun getLivedActivityList(): List<WeakReference<Activity>> {
        return mLivedActivity
    }

    /**
     * 获取当前Activity
     *
     * @return
     */
    fun getCurrentActivity(): Activity? {
        if (mCurrentActivity.empty()) {
            return null
        }
        val activityWeakReference: WeakReference<Activity> = mCurrentActivity.peek() ?: return null
        return activityWeakReference.get()
    }

    fun getResources(): Resources {
        return appContext!!.resources
    }

    fun getString(@StringRes resID: Int): String {
        return appContext!!.resources?.getString(resID)?:""
    }

    ///////////////////////////////////////////////////////////////////////////
    //
    ///////////////////////////////////////////////////////////////////////////
    fun getString(@StringRes resID: Int, vararg formatArgs: Any?): String {
        return appContext!!.resources.getString(resID, *formatArgs)
    }

    fun startActivityByClass(context: Context, clz: Class<*>) {
        val intent = Intent(context, clz)
        if (context !is Activity) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        }
        context.startActivity(intent)
    }
    /**
     * Context Compat
     *
     * http://developer.huawei.com/consumer/cn/devservice/doc/50115
     * 在P版本，如果不在Intent添加FLAG_ACTIVITY_NEW_TASK，将无法通过非Activity的Context启动一个Activity，并且会抛异常。
     *
     * Created by wangwei on 2018/07/23.
     */
    fun startActivity(context: Context, intent: Intent) {
        if (context !is Activity) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        }
        context.startActivity(intent)
    }
}